查看原文
其他

Python面向对象编程从零开始(4)—— 小姐姐请客下篇

2017-06-10 王大伟 Python爱好者社区

(点击上方Python爱好者社区,可快速关注)

作者:王大伟

博客专栏:https://www.hellobi.com/u/wangdawei/articles

Python爱好者社区  唯一小编  

(文末有新福利 

前言

前文传送门:

Python面向对象编程从零开始(1)——从没对象到有对象:https://ask.hellobi.com/blog/wangdawei/8429

Python面向对象编程从零开始(2)—— 与对象相互了解:https://ask.hellobi.com/blog/wangdawei/8446

Python面向对象编程从零开始(3)—— 小姐姐请客上篇:https://ask.hellobi.com/blog/wangdawei/8463

分割线---------------------------------------------------------------------------------------------------------------------------

上次故事说到小姐姐请我吃大(pao)餐(mian),在煮泡面的过程中出了点问题,就是,不管煮多久泡面还是生的。

于是,意识到是代码写的有问题,我们开始修改代码。

class Cook_instant_noodles:
   
   def __init__(self):
       self.cookedState = '生的'
       self.cookedLevel = 0
       
   def __str__(self):
       return '泡面状态:%s(%d)'%(self.cookedState,self.cookedLevel)
   
   def cook(self,cooked_time):
       if cooked_time >= 0 and cooked_time < 3:
           self.cookedState = '还没熟'
       elif cooked_time >= 3 and cooked_time < 5:
           self.cookedState = '半生不熟'
       elif cooked_time >= 5 and cooked_time < 8:
           self.cookedState = '煮熟了'
       elif cooked_time >= 8:
           self.cookedState = '煮糊了'
   
#创建了一个泡面对象
instant_noodles = Cook_instant_noodles()

print(instant_noodles)

#开始煮泡面
instant_noodles.cook(20)

之前发现煮了20分钟,还是生的

泡面煮不熟的原因竟然是

原因在于:


程序执行的流程可以理解为这样:

1.创建了一个对象

2.初始化

3.打印状态

4.打印信息调用(这时候输出的是初始化的信息,所以显示生的)

5.对象调用cook方法,煮20分钟

6.改变属性(cookedState)(这时候属性被改变为 煮糊了)

初步解决问题--更新输出信息

所以,问题出在,我们改变了属性,却没有把改变后的属性显示出来。

所以在最后加上一句即可:

print(instant_noodles)

完整代码:

class Cook_instant_noodles:
   
   def __init__(self):
       self.cookedState = '生的'
       self.cookedLevel = 0
       
   def __str__(self):
       return '泡面状态:%s(%d)'%(self.cookedState,self.cookedLevel)
   
   def cook(self,cooked_time):
       if cooked_time >= 0 and cooked_time < 3:
           self.cookedState = '还没熟'
       elif cooked_time >= 3 and cooked_time < 5:
           self.cookedState = '半生不熟'
       elif cooked_time >= 5 and cooked_time < 8:
           self.cookedState = '煮熟了'
       elif cooked_time >= 8:
           self.cookedState = '煮糊了'
   
#创建了一个泡面对象
instant_noodles = Cook_instant_noodles()

print(instant_noodles)

#开始煮泡面
instant_noodles.cook(20)

print(instant_noodles)


面临新问题,接受挑战!

观察结果,虽然第二次煮了20分钟煮糊了,状态得到改变了,但是,时间却还是显示0分钟,这是为什么呢?

我们回看代码:


我们在cook方法中,通过传参改变的只有cookedState,却没改变cookedLevel的值,所以cookedLevel一直保持初始值为0

再次解决问题--属性大展风采

为了解决这个问题,我们要找个变量,就像累加器一样,每次调用cook方法,我就加上相应的值

那么,在类中,变量其实可以认为用属性替代

我们将cookedLevel这一属性作为累加器

self.cookedLevel += cooked_time

self.cookedLevel += cooked_time  可以理解为  self.cookedLevel = self.cookedLevel + cooked_time

但两者并不是完全相同,以后可能会讲到

这样,每次煮的时间就能累加存储进去了

注意:对象多次调用某个方法,则要想用到上次的结果则要找到当前对象的一个属性,让属性值变化,因为属性值在对象结束时才消失(即理解为关掉程序则消失)

class Cook_instant_noodles:
   
   def __init__(self):
       self.cookedState = '生的'
       self.cookedLevel = 0
       
   def __str__(self):
       return '泡面状态:%s(%d)'%(self.cookedState,self.cookedLevel)
   
   def cook(self,cooked_time):
       
       self.cookedLevel += cooked_time
       
       if cooked_time >= 0 and cooked_time < 3:
           self.cookedState = '还没熟'
       elif cooked_time >= 3 and cooked_time < 5:
           self.cookedState = '半生不熟'
       elif cooked_time >= 5 and cooked_time < 8:
           self.cookedState = '煮熟了'
       elif cooked_time >= 8:
           self.cookedState = '煮糊了'
   
#创建了一个泡面对象
instant_noodles = Cook_instant_noodles()

print(instant_noodles)

#开始煮泡面
instant_noodles.cook(20)

print(instant_noodles)


这下,问题总算是解决了

小姐姐的新困扰--宝宝没煮过面啊

虽然煮面功能完成了,但是小姐姐提出了新问题,她表示之前都是泡面,没煮过面,所以不知道一次煮多久才能保证煮熟(不是生的也不煮糊)

so easy,我说,接下来就是体现面向对象的高端之处了。

因为之前20分钟煮糊了,所以在1~19分钟煮一分钟看一下面的状态就好

可是这怎么实现呢

如果你之前认真阅读并且有点小聪明,则应该看出来了吧

什么?你没看出么

好吧,我来详细分析一下:

我们之前累加了状态并且输出状态,当我们把19分钟划分为1分钟一次依次看泡面状态是不是就ok了

接下来撸起袖子干!


class Cook_instant_noodles:
   
   def __init__(self):
       self.cookedState = '生的'
       self.cookedLevel = 0
       
   def __str__(self):
       return '泡面状态:%s(%d)'%(self.cookedState,self.cookedLevel)
   
   def cook(self,cooked_time):
       
       self.cookedLevel += cooked_time
       
       if cooked_time >= 0 and cooked_time < 3:
           self.cookedState = '还没熟'
       elif cooked_time >= 3 and cooked_time < 5:
           self.cookedState = '半生不熟'
       elif cooked_time >= 5 and cooked_time < 8:
           self.cookedState = '煮熟了'
       elif cooked_time >= 8:
           self.cookedState = '煮糊了'
   
#创建了一个泡面对象
instant_noodles = Cook_instant_noodles()

print(instant_noodles)

#开始煮泡面
instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

看晕了吧,我每次煮一分钟,看一下泡面状态。

我们看看结果


完了,又煮不熟了

回看程序,发现我们最后是不是应该根据总的累积cookedLevel判断状态,而不是一次的cooked_time

所以修改代码,将


中的cooked_time改为self.cookedLevel

class Cook_instant_noodles:
   
   def __init__(self):
       self.cookedState = '生的'
       self.cookedLevel = 0
       
   def __str__(self):
       return '泡面状态:%s(%d)'%(self.cookedState,self.cookedLevel)
   
   def cook(self,cooked_time):
       
       self.cookedLevel += cooked_time
       
       if self.cookedLevel >= 0 and self.cookedLevel < 3:
           self.cookedState = '还没熟'
       elif self.cookedLevel >= 3 and self.cookedLevel < 5:
           self.cookedState = '半生不熟'
       elif self.cookedLevel >= 5 and self.cookedLevel < 8:
           self.cookedState = '煮熟了'
       elif self.cookedLevel >= 8:
           self.cookedState = '煮糊了'
   
#创建了一个泡面对象
instant_noodles = Cook_instant_noodles()

print(instant_noodles)

#开始煮泡面
instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)
print(instant_noodles)


大功告成!通过观察结果,为了节约时间和煤气,5分钟就能煮好泡面。

粗心的小姐姐--吃面不加调料

小姐姐请我吃她煮的面

但我发现!尼玛,怎么没放调料。。。



她解释说,第一次,有点紧张

(旁白:前文说到过,小姐姐第一次煮泡面)

这就是你不放调料的理由???

好吧,我只能:


看来只能先上车后买票了

啊呸,是 先煮面后加调料


加调料怎么加,这是个问题。

我:先加什么,后加什么?

小姐姐:难道不是一次加进去的么,你当你吃拌面啊!?

小姐姐: 

我: 

小姐姐: 

我: 

于是需要将调料加到面里面:

调料作为一些值需要保存在变量里,在面向对象中,则是保存在属性里,又因为有很多种调料,所以我要找个能存放多种调料的容器

在这里我们选择list(列表)作为容器

在属性里定义一个空列表:

self.condiments = []#定义调料列表

定义一个加调料的方法:

def addCondiments(self,item):
       #使用属性保存数据
       self.condiments.append(item)

列表采用append()方法添加元素,这里的传进来的元素参数为item

由于要显示出状态中包含调料,所以要修改__str__()方法

def __str__(self):
       return '泡面状态:%s(%d)'%(self.cookedState,self.cookedLevel)

所以改完之后是这样的:

class Cook_instant_noodles:
   
   def __init__(self):
       self.cookedState = '生的'
       self.cookedLevel = 0
       self.condiments = []#定义调料列表
       
   def __str__(self):
       return '泡面状态:%s(%d)),添加的佐料有:%s'%(self.cookedState,self.cookedLevel,str(self.condiments))
   
   def cook(self,cooked_time):
       
       self.cookedLevel += cooked_time
       
       if self.cookedLevel >= 0 and self.cookedLevel < 3:
           self.cookedState = '还没熟'
       elif self.cookedLevel >= 3 and self.cookedLevel < 5:
           self.cookedState = '半生不熟'
       elif self.cookedLevel >= 5 and self.cookedLevel < 8:
           self.cookedState = '煮熟了'
       elif self.cookedLevel >= 8:
           self.cookedState = '煮糊了'
           
   def addCondiments(self,item):
       #使用属性保存数据
       self.condiments.append(item)

注意:

这里的列表元素(调料)要转成字符串输出

下面,小姐姐开始煮第二碗面给她自己,第一碗面是之前忘加调料煮完的,我默默调料加进去了拌了拌。


#开始煮泡面
instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.addCondiments('菜包')

instant_noodles.addCondiments('粉包')

instant_noodles.addCondiments('酱包')

instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.addCondiments('冰箱里的茶叶蛋')

instant_noodles.addCondiments('冰箱里的火腿肠')

instant_noodles.cook(1)
print(instant_noodles)


instant_noodles.cook(1)
print(instant_noodles)

instant_noodles.cook(1)

小姐姐加的调料:


看到结果的我眼泪掉下来

小姐姐这套路可以的。。。



想继续边听讲故事边零基础学习Python面向对象编程么,请持续关注连载~

新福利:面包君 6月20日在Hellobi Live直播 《互联网金融行业的大数据应用

内容:1、互联网金融的发展历程  2、大数据在互联网金融的应用 3、 征信体系介绍 4、风控反作弊欺诈模型运用 5、互联网金融公司贷款授信 6、保险定价策略分析 7、量化投资应用 

付费参加方式:阅读原文或下图扫码参加

免费参加方式:关注公众号Python爱好者社区,在菜单栏点击免费听课参加活动

关注公众号,“Python爱好者社区”,回复“爬虫”即可获取崔老师爬虫免费学习视频。


Python爱好者社区


为大家提供与Python相关的最新技术和资讯。


长按指纹 > 识别图中二维码 > 添加关注

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存